package bomberman.modelo;

import java.io.IOException;
import java.util.HashSet;

import bomberman.vista.Fondo;
import bomberman.vista.VistaFondo;

import fiuba.algo3.titiritero.modelo.GameLoop;
import fiuba.algo3.titiritero.modelo.ObjetoDibujable;
import fiuba.algo3.titiritero.modelo.ObjetoVivo;
import fiuba.algo3.titiritero.modelo.SuperficieDeDibujo;

public class NuestroGameLoop extends GameLoop {  
	private HashSet<ObjetoVivo>      objetosVivosAAgregar;
	private HashSet<ObjetoDibujable> objetosDibujablesAAgregar;
	private HashSet<ObjetoVivo>      objetosVivosARemover;
	private HashSet<ObjetoDibujable> objetosDibujablesARemover;
	private VistaFondo			   fondo;
  
	public NuestroGameLoop(int frecuencia, SuperficieDeDibujo superficieDeDibujo) {
		super(frecuencia, superficieDeDibujo);
		inicializar();
	}
  
	public NuestroGameLoop(SuperficieDeDibujo superficieDeDibujo) {
		super(superficieDeDibujo);
		inicializar();
	}
  
	private void inicializar() {
	    objetosVivosAAgregar = new HashSet<ObjetoVivo>();
	    objetosDibujablesAAgregar = new HashSet<ObjetoDibujable>();
	    objetosVivosARemover = new HashSet<ObjetoVivo>();
	    objetosDibujablesARemover = new HashSet<ObjetoDibujable>();
	    
	    try {
			fondo = new VistaFondo(new Fondo());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
  
	public void agregar(ObjetoVivo unObjetoVivo) {
		objetosVivosAAgregar.add(unObjetoVivo);
	}
  
	public void remover(ObjetoVivo unObjetoVivo) {
		objetosVivosARemover.add(unObjetoVivo);
	}
  
  	public void agregar(ObjetoDibujable unObjetoDibujable) {
  		objetosDibujablesAAgregar.add(unObjetoDibujable);
  	}
  
	public void remover(ObjetoDibujable unObjetoDibujable) {
		objetosDibujablesARemover.add(unObjetoDibujable);
  	}
  
	@Override
	public void run() {
		while (estaEjecutando()) {
			SuperficieDeDibujo unaSuperficieDeDibujo = getSuperficieDeDibujo();

			for (ObjetoVivo objetoVivo: getObjetosVivos()) {
				objetoVivo.vivir();
			}

			if (!objetosVivosAAgregar.isEmpty()) {
				for (ObjetoVivo objetoVivo: objetosVivosAAgregar) {
					super.agregar(objetoVivo);
				}

				objetosVivosAAgregar.clear();
			}

			if (!objetosVivosARemover.isEmpty()) {
				for (ObjetoVivo objetoVivo: objetosVivosARemover) {
					super.remover(objetoVivo);
				}

				objetosVivosARemover.clear();
			}

			if (!objetosDibujablesAAgregar.isEmpty()) {
				for (ObjetoDibujable objetoDibujable: objetosDibujablesAAgregar) {
					super.agregar(objetoDibujable);
				}

				objetosDibujablesAAgregar.clear();
			}

			if (!objetosDibujablesARemover.isEmpty()) {
				for (ObjetoDibujable objetoDibujable: objetosDibujablesARemover) {
					super.remover(objetoDibujable);
				}

				objetosDibujablesARemover.clear();
			}
	  
			try {
				fondo.dibujar(unaSuperficieDeDibujo);
			} catch (ClassCastException e){ }
      
			for (ObjetoDibujable objetoDibujable: getObjetosDibujables()) {
				objetoDibujable.dibujar(unaSuperficieDeDibujo);
			}
      
			unaSuperficieDeDibujo.actualizar();
      
			try {
				Thread.sleep(getFrecuencia());
			} catch (InterruptedException e) { }
		}
	}
  
	public NuestroGameLoop reiniciar() {
		return new NuestroGameLoop(getFrecuencia(), getSuperficieDeDibujo());
	}
}
